package com.tianyuan.lims.dms.controller.exam.service;

import com.jfinal.plugin.activerecord.Db;
import com.tianyuan.lims.dms.entity.LimsExamQuestion;
import org.apache.poi.ss.usermodel.*;
import java.io.File;
import java.io.FileInputStream;
import java.util.*;
import java.util.regex.Pattern;

import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;

public class QuestionImportService {

    // 验证正确答案的正则（仅A/B/C/D）
    private static final Pattern ANSWER_PATTERN = Pattern.compile("^[A-D]$");

    /**
     * 解析文件并导入（返回任务ID）
     */
    public String importQuestions(File file, String fileName, Integer categoryId) throws Exception {
        String taskId = UUID.randomUUID().toString(); // 生成任务ID
        List<LimsExamQuestion> questionList = new ArrayList<>();

        // 根据文件后缀解析
        if (fileName.endsWith(".xlsx") || fileName.endsWith(".xls")) {
            questionList = parseExcel(file);
        } else if (fileName.endsWith(".csv")) {
            questionList = parseCsv(file);
        } else {
            throw new IllegalArgumentException("不支持的文件格式");
        }

        // 验证数量
        if (questionList.size() > 1000) {
            throw new IllegalArgumentException("单文件最大50MB，单次最多导入1000道题，支持.xlsx/.xls/UTF-8编码CSV格式");
        }

        // 字段验证并保存到临时表
        for (LimsExamQuestion q : questionList) {
            q.setType(categoryId);
            String errorMsg = validateQuestion(q);
            if (errorMsg != null) {
                q.setImportStatus(2); // 导入失败
                q.setErrorMsg(errorMsg);
            } else {
                q.setImportStatus(1); // 待确认导入
                q.setErrorMsg(null);
            }
            q.set("taskId", taskId); // 关联任务ID
            q.save();
        }

        return taskId;
    }

    /**
     * 验证题目字段
     */
    private String validateQuestion(LimsExamQuestion q) {
        // 验证题目内容
        String content = q.getContent();
        if (content == null || content.trim().isEmpty()) {
            return "题目内容不能为空";
        }
        if (content.length() > 500) {
            q.setContent(content.substring(0, 500)); // 截断
            return "题目内容超过500字符，已自动截断";
        }

        // 验证选项
        String[] options = {q.getOptionA(), q.getOptionB(), q.getOptionC(), q.getOptionD()};
        for (int i = 0; i < options.length; i++) {
            String opt = options[i];
            if (opt == null || opt.trim().isEmpty()) {
                return "选项" + (char) ('A' + i) + "不能为空";
            }
            if (opt.length() > 200) {
                return "选项" + (char) ('A' + i) + "字符数超过200，需精简后重新导入";
            }
        }

        // 验证正确答案
        String answer = q.getAnswer();
        if (answer == null || !ANSWER_PATTERN.matcher(answer).matches()) {
            return "正确答案仅支持A/B/C/D，导入失败";
        }

        return null; // 验证通过
    }

    // 解析Excel文件（省略实现）
    private List<LimsExamQuestion> parseExcel(File file) throws Exception {
        List<LimsExamQuestion> list = new ArrayList<>();
        try (Workbook workbook = WorkbookFactory.create(new FileInputStream(file))) {
            Sheet sheet = workbook.getSheetAt(0);
            // 从第2行开始解析（第1行为表头）
            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row == null) continue;

                LimsExamQuestion q = new LimsExamQuestion();
                q.setContent(getCellValue(row.getCell(0)));
                q.setOptionA(getCellValue(row.getCell(1)));
                q.setOptionB(getCellValue(row.getCell(2)));
                q.setOptionC(getCellValue(row.getCell(3)));
                q.setOptionD(getCellValue(row.getCell(4)));
                q.setAnswer(getCellValue(row.getCell(5)));
                list.add(q);
            }
        }
        return list;
    }

    // 解析CSV文件（省略实现）
    private List<LimsExamQuestion> parseCsv(File file) throws Exception {
        // 实现UTF-8编码CSV解析逻辑
        return new ArrayList<>();
    }

    // 获取Excel单元格值（省略实现）
    private String getCellValue(Cell cell) {
        if (cell == null) return "";
        // 实现不同类型单元格的取值逻辑
        return cell.toString();
    }

    // 以下为辅助方法（省略实现）
    public List<LimsExamQuestion> getImportPreview(String taskId, int limit) {
        return LimsExamQuestion.dao.find("select * from lims_exam_question where taskId = ? limit ?", taskId, limit);
    }

    public int getTotalCount(String taskId) {
        return Db.queryInt("select count(*) from lims_exam_question where taskId = ?", taskId);
    }

    public int getErrorCount(String taskId) {
        return Db.queryInt("select count(*) from lims_exam_question where taskId = ? and importStatus = 2", taskId);
    }

    public boolean confirmImport(String taskId) {
        // 将待导入状态（1）更新为正式导入状态
        int count = Db.update("update lims_exam_question set importStatus = 1 where taskId = ? and importStatus = 1", taskId);
        return count >= 0;
    }

    /**
     * 下载导入错误列表（导出为Excel）
     *
     * @param taskId   导入任务ID
     * @param response HTTP响应对象
     */
    public void downloadErrorList(String taskId, HttpServletResponse response) {
        OutputStream os = null;
        Workbook workbook = null;
        try {
            // 1. 查询该任务下所有导入失败的题目
            List<LimsExamQuestion> errorList = LimsExamQuestion.dao.find(
                    "select content, option_a, option_b, option_c, option_d, answer, errorMsg " +
                            "from lims_exam_question " +
                            "where taskId = ? and importStatus = 2 " + // importStatus=2表示导入失败
                            "order by id asc",
                    taskId
            );

            if (errorList.isEmpty()) {
                // 无错误数据时返回提示
                response.setContentType("text/plain;charset=UTF-8");
                response.getWriter().write("当前任务无错误数据");
                return;
            }

            // 2. 创建Excel工作簿
            workbook = new XSSFWorkbook(); // 使用xlsx格式（支持2007+版本）
            Sheet sheet = workbook.createSheet("导入错误列表");

            // 3. 创建表头
            String[] headers = {
                    "题目内容", "选项A", "选项B", "选项C", "选项D", "正确答案", "错误原因"
            };
            Row headerRow = sheet.createRow(0);
            CellStyle headerStyle = workbook.createCellStyle();
            Font headerFont = workbook.createFont();
            headerFont.setBold(true); // 表头加粗
            headerStyle.setFont(headerFont);

            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
                sheet.autoSizeColumn(i); // 自动调整列宽
            }

            // 4. 填充错误数据
            CellStyle errorStyle = workbook.createCellStyle();
            Font errorFont = workbook.createFont();
            errorFont.setColor(Font.COLOR_RED); // 错误原因红色显示
            errorStyle.setFont(errorFont);

            for (int i = 0; i < errorList.size(); i++) {
                LimsExamQuestion question = errorList.get(i);
                Row dataRow = sheet.createRow(i + 1); // 从第2行开始（0是表头）

                // 填充数据单元格
                dataRow.createCell(0).setCellValue(question.getContent());
                dataRow.createCell(1).setCellValue(question.getOptionA());
                dataRow.createCell(2).setCellValue(question.getOptionB());
                dataRow.createCell(3).setCellValue(question.getOptionC());
                dataRow.createCell(4).setCellValue(question.getOptionD());
                dataRow.createCell(5).setCellValue(question.getAnswer());

                // 错误原因用红色显示
                Cell errorCell = dataRow.createCell(6);
                errorCell.setCellValue(question.getErrorMsg());
                errorCell.setCellStyle(errorStyle);
            }

            // 5. 设置响应头，触发文件下载
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            String fileName = "题目导入错误列表_" + taskId.substring(0, 8) + ".xlsx";
            // 处理中文文件名编码（兼容各浏览器）
            String encodedFileName = URLEncoder.encode(fileName, "UTF-8")
                    .replace("+", "%20"); // 替换空格编码
            response.setHeader("Content-Disposition",
                    "attachment; filename=\"" + encodedFileName + "\"; filename*=UTF-8''" + encodedFileName);
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);

            // 6. 写入响应流
            os = response.getOutputStream();
            workbook.write(os);
            os.flush();
        } catch (Exception e) {
            e.printStackTrace();
            try {
                response.setContentType("text/plain;charset=UTF-8");
                response.getWriter().write("下载失败：" + e.getMessage());
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        } finally {
            // 7. 关闭资源
            try {
                if (os != null) os.close();
                if (workbook != null) workbook.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }







}
